package com.mall.order.services;

import com.mall.commons.tool.exception.BizException;
import com.mall.order.OrderCoreService;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.factory.OrderProcessPipelineFactory;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.Order;
import com.mall.order.dal.entitys.OrderItem;
import com.mall.order.dal.entitys.OrderShipping;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.order.dal.persistence.OrderShippingMapper;
import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.*;
import com.mall.order.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * cskaoyan
 */
@Slf4j
@Component
@Service(cluster = "failfast")
public class OrderCoreServiceImpl implements OrderCoreService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    StockMapper stockMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;


    /**
     * 创建订单的处理流程
     *
     * @param request
     * @return
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        CreateOrderResponse response = new CreateOrderResponse();
        try {
            //创建pipeline对象
            TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

            //启动pipeline
            invoker.start(); //启动流程（pipeline来处理）

            //获取处理结果
            AbsTransHandlerContext context = invoker.getContext();

            //把处理结果转换为response
            response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest cancelOrderRequest) {
        CancelOrderResponse cancelOrderResponse = new CancelOrderResponse();
        try {
            // 1 参数校验
            cancelOrderRequest.requestCheck();

            // 2 设置订单状态为 订单关闭(5)
            Order order = new Order();
            order.setOrderId(cancelOrderRequest.getOrderId());
            order.setStatus(5);
            int orderRows = orderMapper.updateByPrimaryKeySelective(order);
            if (orderRows != 1) {
                throw new BizException(OrderRetCode.DB_EXCEPTION.getCode(),
                        OrderRetCode.DB_EXCEPTION.getMessage()+", 订单号错误");
            }

            // 3 更改 order_item表 和 stock表
            Example orderItemExample = new Example(OrderItem.class);
            orderItemExample.createCriteria().andEqualTo("orderId", cancelOrderRequest.getOrderId());
            List<OrderItem> orderItems = orderItemMapper.selectByExample(orderItemExample);
            if (orderItems == null || orderItems.size() == 0) {
                throw new BizException(OrderRetCode.DB_EXCEPTION.getCode(),
                        OrderRetCode.DB_EXCEPTION.getMessage()+", 商品订单表错误");
            }

            for (OrderItem orderItem : orderItems) {
                // 3.1 如果此时库存处于锁定状态(1)，则更改为 已经释放(2)
                if (orderItem.getStatus() != 1) {
                    continue;
                }
                orderItem.setStatus(2);
                orderItemMapper.updateByExampleSelective(orderItem, orderItemExample);
                // 3.2 更改stock表，释放库存
                Stock stock = new Stock();
                stock.setItemId(orderItem.getItemId());
                stock.setStockCount(orderItem.getNum().longValue());
                stock.setLockCount(-1 * orderItem.getNum());
                stockMapper.updateStock(stock);
            }

            // 4 封装 CancelOrderResponse 返回
            cancelOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
            cancelOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("OrderCoreServiceImpl.cancleOrder 异常");
            ExceptionProcessorUtils.wrapperHandlerException(cancelOrderResponse, e);
        }
        return cancelOrderResponse;
    }

    @Override
    public DeleteOrderResponse deleteOrder(String id) {
        DeleteOrderResponse deleteOrderResponse = new DeleteOrderResponse();
        Order order = new Order();
        order.setOrderId(id);
        //更具订单查询状态
        Order selectByPrimaryKey = orderMapper.selectByPrimaryKey(id);
        //删除订单
        int i = orderMapper.deleteByPrimaryKey(id);
        //查出订单所有商品
        Example example = new Example(OrderItem.class);
        example.createCriteria().andEqualTo("orderId", id);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
        //删除库存
        Example orderItemExample = new Example(OrderItem.class);
        orderItemExample.createCriteria().andEqualTo("orderId", id);
        int i1 = orderItemMapper.deleteByExample(orderItemExample);
        //删除地址表
        Example orderShippingExample = new Example(OrderShipping.class);
        orderShippingExample.createCriteria().andEqualTo("orderId", id);
        int i2 = orderShippingMapper.deleteByExample(orderShippingExample);
        //更具状态决定是否返回库存
        Integer status = selectByPrimaryKey.getStatus();
        if (status.intValue() == 0) {
            for (OrderItem orderItem : orderItems) {
                Example example1 = new Example(Stock.class);
                example1.createCriteria().andEqualTo("itemId", orderItem.getItemId());
                Stock stock = new Stock();
                stock.setItemId(orderItem.getItemId());
                stock.setStockCount(orderItem.getNum().longValue());
                stock.setLockCount(-1 * orderItem.getNum());
                stockMapper.updateStock(stock);
            }
        }
        if (i < 1) {
            deleteOrderResponse.setCode(OrderRetCode.DB_SAVE_EXCEPTION.getCode());
            deleteOrderResponse.setMsg(OrderRetCode.DB_SAVE_EXCEPTION.getMessage());
        }
        deleteOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
        deleteOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        return deleteOrderResponse;
    }

}
